﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Bluyel.Core
{
    /// <summary>
    /// A generic list of types.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ListTypeGen<T>
        where T : IType
    {
        private string _name;

        private List<T> _listType = new List<T>();

        //=====================================================================
        #region Constructor.

        //---------------------------------------------------------------------
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="name"></param>
        public ListTypeGen()
        {
            _name = "ListTypeGen";
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="name"></param>
        public ListTypeGen(string name)
        {
            _name = name;
        }
        #endregion

        //=====================================================================
        #region Properties.

        //---------------------------------------------------------------------
        public string Name
        { get { return _name; } }

        //---------------------------------------------------------------------
        public IEnumerable<T> ListType
        {
            get { return _listType; }
        }

        #endregion

        //=====================================================================
        #region Public Add/Update methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// Add a new type, must be valid (id and name).
        /// 
        /// Check that the same is not already added.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public bool Add(T type)
        {
            if (type == null)
                return false;

            // check that the type is not already present
            if (_listType.Contains(type))
                return false;
            if (FindTypeById(type.Id) != null)
                return false;
            if (FindTypeByName(type.Name) != null)
                return false;

            _listType.Add(type);
            return true;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Remove the type by the name.
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool Remove(string name)
        {
            if (string.IsNullOrWhiteSpace(name))
                return false;

            T d = FindTypeByName(name);
            if (d == null)
                return false;

            return _listType.Remove(d);
        }

        /// <summary>
        /// remove the type, by the instance.
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool Remove(T d)
        {
            if (d == null)
                return false;
            if (!_listType.Contains(d))
                return false;

            return _listType.Remove(d);
        }

        #endregion


        //=====================================================================
        #region Public Find methods.

        //---------------------------------------------------------------------
        public T FindTypeById(UniqueId id)
        {
            if (id==null)
                // return null if name is wrong
                return default(T);

            return _listType.Find(t => t.Id.IdAreEquals(id));
        }

        //---------------------------------------------------------------------
        public T FindTypeById(string idStr)
        {
            if (string.IsNullOrWhiteSpace(idStr))
                // return null if name is wrong
                return default(T);

            return _listType.Find(t => t.Id.IdAreEquals(idStr));
        }

        //---------------------------------------------------------------------
        public T FindTypeByName(string name)
        {
            if (string.IsNullOrWhiteSpace(name))
                // return null if name is wrong
                return default(T);

            return _listType.Find(t => t.Name.Equals(name,StringComparison.InvariantCultureIgnoreCase));
        }
        #endregion

    }
}
